package com.jingdianjichi.subject.service.impl;

import com.jingdianjichi.subject.common.entity.PageResult;
import com.jingdianjichi.subject.common.enums.IsDeleteEnum;
import com.jingdianjichi.subject.convert.SubjectInfoConverter;
import com.jingdianjichi.subject.entity.SubjectInfoBO;
import com.jingdianjichi.subject.entity.SubjectOptionBO;
import com.jingdianjichi.subject.handler.SubjectTypeHandler;
import com.jingdianjichi.subject.handler.SubjectTypeHandlerFactory;
import com.jingdianjichi.subject.infra.basic.entity.SubjectInfo;
import com.jingdianjichi.subject.infra.basic.entity.SubjectMapping;
import com.jingdianjichi.subject.infra.basic.service.impl.SubjectInfoServiceImpl;
import com.jingdianjichi.subject.infra.basic.service.impl.SubjectMappingServiceImpl;
import com.jingdianjichi.subject.service.SubjectInfoDomainService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.List;

/**
 *
 *
 * @author makejava
 * @since 2025-07-30 09:20:01
 */
@Service
public class SubjectInfoDomainServiceImpl implements SubjectInfoDomainService {
    @Resource
    private SubjectTypeHandlerFactory subjectTypeHandlerFactory;
    @Autowired
    private SubjectInfoServiceImpl subjectInfoService;
    @Autowired
    private SubjectMappingServiceImpl subjectMappingService;

    /**
     * 新增数据
     *
     * @param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(SubjectInfoBO subjectInfoBO) {
        //如果说所有判断插入题型逻辑都放到主流程里面
        //那么如果判断逻辑复杂，主流程代码会非常长，不利于维护
        //这里直接使用工厂+策略模式
        //先是一个题型接口有返回对应题目类型枚举的方法，还有一个插入的功能方法，因为不同题型插入的具体逻辑不一样
        //然后四个题型实现上述接口
        //最后通过工厂根据题型枚举获取对应的题型实现类，然后调用插入方法
        SubjectInfo subjectInfo = SubjectInfoConverter.Instatnce.convertBOToEntity(subjectInfoBO);
        subjectInfo.setIsDeleted(IsDeleteEnum.UN_DELETED.getCode());
        //插入主题目表
        subjectInfoService.insert(subjectInfo);
        subjectInfoBO.setId(subjectInfo.getId());
        System.out.println(subjectInfo.getId());
        SubjectTypeHandler handler = subjectTypeHandlerFactory.getHandler(subjectInfo.getSubjectType());
        //插入题目类型表
        handler.add(subjectInfoBO);
        //插入题目映射关系表mapping
        List<SubjectMapping> subjectMappingList=new LinkedList<>();
        subjectInfoBO.getCategoryIds().forEach(categoryId->{
            subjectInfoBO.getLabelIds().forEach(labelId->{
                SubjectMapping subjectMapping=new SubjectMapping();
                subjectMapping.setSubjectId(subjectInfo.getId());
                subjectMapping.setCategoryId(categoryId);
                subjectMapping.setLabelId(labelId);
                subjectMapping.setIsDeleted(IsDeleteEnum.UN_DELETED.getCode());
                subjectMappingList.add(subjectMapping);
            });
        });
        subjectMappingService.batchInsert(subjectMappingList);

    }

    @Override
    public PageResult<SubjectInfoBO> getSubjectPage(SubjectInfoBO subjectInfoBO) {
        PageResult<SubjectInfoBO> pageResult=new PageResult<>();
        pageResult.setPageSize(subjectInfoBO.getPageSize());
        pageResult.setPageNo(subjectInfoBO.getPageNo());
        //算start用于limit
        int start = (pageResult.getPageNo() - 1) * pageResult.getPageSize();
        //再构建实体类传输条件做查询
        SubjectInfo subjectInfo = SubjectInfoConverter.Instatnce.convertBOToEntity(subjectInfoBO);
        //由于传输的分类id和标签id不在subject实体类中，所以需要额外传输
        int count=subjectInfoService.countByCondition(subjectInfo,
                subjectInfoBO.getCategoryId(),subjectInfoBO.getLabelId());
        if(count==0)return pageResult;
        List<SubjectInfo> subjectInfoList= subjectInfoService.queryPage(subjectInfo,subjectInfoBO.getCategoryId(),subjectInfoBO.getLabelId()
                , start,pageResult.getPageSize());
        List<SubjectInfoBO> subjectInfoBOS = SubjectInfoConverter.Instatnce.convertEntityToBO(subjectInfoList);
        pageResult.setRecords(subjectInfoBOS);
        pageResult.setTotal(count);
        return pageResult;

    }

    @Override
    public SubjectInfoBO querySubjectInfo(SubjectInfoBO subjectInfoBO) {
        //根据id查出实体类
        SubjectInfo subjectInfo = subjectInfoService.queryById(subjectInfoBO.getId());
        if(subjectInfo==null)
            return null;
        //此时还缺少答案，和选项内容，以及标签名字
        //根据不同题型查询再次利用工厂策略选择，在工厂添加查询方法
        //缺少标签名和缺少答案和选项内容，再抽取一个optionBO组成答案和选项内容
        SubjectTypeHandler handler = subjectTypeHandlerFactory.getHandler(subjectInfo.getSubjectType());
        //根据不同题型表查询填充答案属性和选项属性，
        SubjectOptionBO subjectOptionBO=handler.query(subjectInfoBO.getId());
        //还差标签名,根据mapping表联表查询label表得到
        List<String> labelNames=subjectMappingService.queryLabelNameBySubjectId(subjectInfoBO.getId());
        subjectInfoBO.setLabelName(labelNames);
        //之后利用convertor转换器将option转为infobo
        SubjectInfoBO subjectInfoBO1 = SubjectInfoConverter.Instatnce.convertBOAndOptionToBO(subjectOptionBO, subjectInfoBO);
        return subjectInfoBO1;

    }

}
